package com.song.demo.webmvc.aop;

import lombok.Data;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 执行拦截器链 相当于spring中的ReflectiveMethodInvocation的功能
 */
@Data
public class GPMethodInvocation implements GPJoinPoint{

    private Object proxy;//代理对象

    private Method method;//代理的目标方法

    private Object target;//代理的目标对象

    private Class<?> targetClass;//代理类的目标类

    private Object[] arguments;//代理的方法的实参列表

    private List<Object> interceptorsAndDynamicMethodMatches;//回调方法链

    private Map<String,Object> userAttributes = new HashMap<>();//保存自定义属性

    private int currentInterceptorIndex = -1;



    public GPMethodInvocation(Object proxy, Object target, Method method, Object[] args, Class targetClass, List<Object> methods) {
        this.proxy = proxy;
        this.target = target;
        this.method = method;
        this.arguments = args;
        this.targetClass = targetClass;
        this.interceptorsAndDynamicMethodMatches = methods;
    }


    public Object proceed() throws Throwable{
        if (this.currentInterceptorIndex ==this.interceptorsAndDynamicMethodMatches.size() -1){
            return this.method.invoke(this.target,this.arguments);
        }
        Object interceptorsAndDynamicMethod = this.interceptorsAndDynamicMethodMatches.get(++this.currentInterceptorIndex);
        //如果要动态匹配joinPoint
        if (interceptorsAndDynamicMethod instanceof GPMethodInterceptor){
            GPMethodInterceptor mi = (GPMethodInterceptor)interceptorsAndDynamicMethod;
            return mi.invoke(this);
        }else{
            return proceed();
        }
    }


    @Override
    public Object getThis() {
        return this.target;
    }

    @Override
    public void setUserAttribute(String key, Object value) {
        userAttributes.put(key,value);
    }

    @Override
    public Object getUserAttribute(String key) {
        return userAttributes.get(key);
    }
}
